#ifndef __CACHEENTRY_H__
#define __CACHEENTRY_H__

#include "base/LoadRequest.h"
#include "base/Processor.h"
#include "base/Simulator.h"
#include "base/StoreRequest.h"
#include "base/simtypes.h"
#include "mem/LineFlags.h"

class CacheHash;

class CacheEntry {
public:
    NEW_DELETE_OPERATORS_H(CacheEntry,NoSuper);

    CacheEntry(LineFlags* flags_,
               Processor* processor_);

    ~CacheEntry();

private:
    // private to prevent use unless later we declare working versions
    CacheEntry(CacheEntry const & rhs);
    CacheEntry const & operator= (CacheEntry const & rhs);

    /** 
        age for LRU purposes
    */
    unsigned long long _age;

    bool inVictimCache;

public:
    // fixed values
    LineFlags*         flags;
    Processor* const   processor;
    uint               data[MAX_BLOCK_SIZE/sizeof(uint)];

    /** 
        touch to update LRU information
     */
    void touch () {
        _age = global_sim->getSimclock();
    }

    /** 
        access LRU information
    */
    unsigned long long getAge () const { 
        return _age; 
    }

    /** 
        in what structure am I to be found?
    */
    CacheHash* location; 

    VA getAddress () const { return flags->getAddress(); }
    uint getBlockSize () const { return flags->getBlockSize(); }

    Processor* getProcessor () const { return processor; }
    void checkSanity ();

    bool isInVictimCache () { return inVictimCache; }
    void setInVictimCache (bool b) { inVictimCache = b; }
};

struct CacheEntryAgeLessThan {
    bool operator () (CacheEntry const* const lhs, CacheEntry const* const rhs) {
        return lhs->getAge() < rhs->getAge();
    }
};

struct CacheEntryFlagsLessThan {
    bool operator () (CacheEntry* x, CacheEntry* y) {
        return x->flags->ltFunctor(y->flags);
    }
};

#endif // __CACHEENTRY_H__
